#include<iostream>
#include<vector>
using namespace std;      // 使用标准命名空间，避免每次调用std::前缀

const int MAXN = 1e5 + 5; // 定义最大节点数，用于数组大小定义（题目限制n<=1e5）

vector<int> adj[MAXN];    // 邻接表存储树结构，adj[i]表示与i相连的所有边

int n, m;                 // n: 节点数量；m: 可忍受的最大连续猫的数量

int a[MAXN];              // a[i]: 表示第i个节点是否有猫（1=有猫，0=无猫）

int ans = 0;              // 记录满足条件的餐厅数量（即合法叶子节点的数量）

// 深度优先搜索函数
// node: 当前访问的节点编号
// parent: 当前节点的父节点（防止回溯）
// consecutive_cats: 到当前节点为止路径上的连续猫的数量
void dfs(int node, int parent, int consecutive_cats) {
    if (a[node]) {                        // 如果当前节点有猫
        consecutive_cats += 1;            // 连续猫的数量加一
    } else {                              // 否则（当前节点没有猫）
        consecutive_cats = 0;             // 重置连续猫的数量为0
    }

    if (consecutive_cats > m) {           // 如果连续猫的数量超过m（阿迪不能接受）
        return;                           // 剪枝，不再继续探索这条路径
    }

    bool is_leaf = true;                  // 初始化标记为“是叶子节点”

    for (int neighbor : adj[node]) {      // 遍历当前节点的所有邻居
        if (neighbor != parent) {         // 如果邻居不是父节点（防止回头）
            is_leaf = false;              // 说明当前节点不是叶子节点
            dfs(neighbor, node, consecutive_cats); // 继续DFS遍历子节点
        }
    }

    if (is_leaf) {                        // 如果是叶子节点
        ans++;                            // 满足条件，计数器加一
    }
}

int main() {
    cin >> n >> m;                        // 输入n和m

    for (int i = 1; i <= n; ++i) {        // 输入每个节点是否有猫
        cin >> a[i];                      // 存入数组a[1..n]
    }

    for (int i = 0; i < n - 1; ++i) {     // 树共有n-1条边
        int u, v;                         // 输入边的两个端点u和v
        cin >> u >> v;

        adj[u].push_back(v);              // 将边添加到邻接表中（双向）
        adj[v].push_back(u);
    }

    dfs(1, -1, 0);                        // 从根节点1开始DFS遍历，初始父节点设为-1，连续猫数为0

    cout << ans << endl;                  // 输出最终结果：满足条件的餐厅数量

    return 0;                             // 程序正常结束
}